function isObject(value: any) {
  return Object.prototype.toString.call(value) === '[object Object]';
}
function isString(value: any) {
  return Object.prototype.toString.call(value) === '[object String]';
}

const deepSetValue: (
  obj: Record<string, any>,
  path: string[],
  key: string,
  value: any,
  deepKey: string,
) => boolean = (obj, path, key, value, deepKey) => {
  if (!Array.isArray(path)) {
    console.warn('路径解析错误，路径必须是一个数组');
    return true;
  }
  if (path.length > 0) {
    if (obj[key] !== undefined && !isObject(obj[key])) {
      console.warn('路径解析错误，路径节点必须是对象类型');
      return true;
    }

    if (obj[key] === undefined) {
      obj[key] = {};
    }
    // 移除第一个路径节点
    path.shift();
    return deepSetValue(obj[key], path, path[0], value, deepKey) ? true : false;
  }

  obj[deepKey] = value;

  return true;
};

const deepGetValue = (obj: Record<string, any>, path: string, key: string) => {
  if (!key || !isObject(obj)) return '';

  let pathArray = path.split('.');
  pathArray = pathArray.filter((el) => {
    return el !== '';
  });

  let result = obj;
  for (let index = 0; index < pathArray.length; index++) {
    result = result[pathArray[index]];
    if (isObject(result)) continue;
    console.warn(`路径解析异常，请确认路径节点${pathArray[index]}是否一个对象`);
    break;
  }

  if (!isObject(result)) {
    console.warn('路径尾节点非对象');
    return result;
  }
  return result[key];
};

export default class TDbStorage {
  private _name: string;
  constructor(name: string, info: any = {}, cover: boolean = false) {
    this._name = name;

    this.init(name, info, cover);
  }
  init(name: string, info: any, cover: boolean) {
    if (!this._initEnv())
      throw new Error('环境异常，这是一个操作localStorage的轻量级工具，请在浏览器端运行');

    let currentData = window.localStorage.getItem(name) || '{}';
    if (cover) {
      currentData = info;
    }

    window.localStorage.setItem(name, JSON.stringify(JSON.parse(currentData)));
  }
  /**
   * 环境检测
   * @returns {Boolean} true - 合法环境, false - 非法环境
   */
  private _initEnv() {
    // 不存在window对象
    if (typeof window === 'undefined') return false;
    // 不存在document.body
    if (typeof document.body === 'undefined') return false;

    return true;
  }
  /**
   * 设置属性
   * @param {saveData} info config
   * @returns {Boolean} true - 成功, false - 失败
   */
  set(info: TD.saveData) {
    if (!isString(info.path) && info.path !== undefined) {
      console.warn(`路径解析异常,必须是一个字符串`);
      return false;
    }

    if (info.name === '' || !info.name) {
      info.name = this._name;
    }

    const localData = window.localStorage.getItem(this._name);
    if (!localData) {
      console.warn(`当前 ${this._name} 数据不存在`);
      return false;
    }
    const localDataObj = JSON.parse(localData);

    if (info.path === undefined) {
      info.path = '';
    }
    let pathArray = info.path.split('.');
    pathArray = pathArray.filter((el) => {
      return el !== '';
    });

    deepSetValue(localDataObj, pathArray, pathArray[0], info.value, info.name);

    window.localStorage.setItem(this._name, JSON.stringify(localDataObj));

    return true;
  }
  /**
   * 获取属性
   */
  get(info?: TD.getData) {
    const localData = window.localStorage.getItem(this._name) || '';

    if (!localData) {
      console.warn(`当前 ${this._name} 数据不存在`);
      return '';
    }

    if (!info) {
      return JSON.parse(localData);
    }

    if (!isString(info.path) && info.path !== undefined) {
      console.warn(`路径解析异常,必须是一个字符串`);
      return '';
    }

    const localDataObj = JSON.parse(localData);

    if (info.path === undefined) {
      info.path = '';
    }

    const data = deepGetValue(localDataObj, info.path, info.name);
    return data;
  }
}
